package com.jason.common.file.word.util;

import com.jason.common.file.config.StorageConfig;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.CannedAccessControlList;
import com.qcloud.cos.model.CreateBucketRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;

/**
 * 文件服务器操作工具类
 *
 * @author guozhongcheng
 * @since 2023/10/19
 **/
@Slf4j
public final class FileServerUtil {

    /**
     * 上传图片
     *
     * @param storageConfig   存储配置
     * @param fileNameAndType 文件名称+类型
     * @param inputStream     文件输入流
     * @return 图片资源路径
     * @throws IOException IO异常
     */
    public static String uploadPicture(StorageConfig storageConfig, String fileNameAndType, InputStream inputStream) {
        try {
//            String key = StrUtil.getObjectName(storageConfig.getFileDir(), "", FileUtil.extName(fileNameAndType));
//            return putObjectForInputStream(storageConfig, key, inputStream, fileNameAndType,
//                    new MimetypesFileTypeMap().getContentType(fileNameAndType), CannedAccessControlList.PublicRead);
        } catch (Exception e) {
            log.error("上传图片到文件服务器发生异常:", e);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    log.error("上传图片到文件服务器后关闭文件输入流发生异常:", e);
                }
            }
        }
        return "";
    }

    /**
     * 将文件输入流放入对象中
     *
     * @param storageConfig           存储对象
     * @param key                     文件ID
     * @param inputStream             文件输入流
     * @param fileNameAndType         文件名称+类型
     * @param contentType             http内容类型
     * @param cannedAccessControlList 关闭访问控制列表
     * @return 图片资源地址
     */
    private static String putObjectForInputStream(StorageConfig storageConfig, String key,
                                                  InputStream inputStream, String fileNameAndType,
                                                  String contentType,
                                                  CannedAccessControlList cannedAccessControlList) {
        ObjectMetadata meta = new ObjectMetadata();
        PutObjectRequest putObjectRequest = new PutObjectRequest(storageConfig.getTencentBucket(), key, inputStream, meta);
        putObjectRequest.setCannedAcl(cannedAccessControlList);
        COSClient cosClient = getCOSClient(storageConfig);
        String checkUrl = "";
        try {
            meta.setContentDisposition("attachment;filename=\"" + java.net.URLEncoder.encode(fileNameAndType, "UTF-8") + "\"");
            // 设置内容类型
            meta.setContentType(contentType);
            // 设置上传内容长度
            int available = inputStream.available();
            meta.setContentLength(available);
            // 放入上传对象
            cosClient.putObject(putObjectRequest);
            checkUrl = checkUrl(storageConfig.getTencentCosUrl(), key);
        } catch (Exception e) {
            log.error("存储腾讯云COS错误发生异常:", e);
        } finally {
            cosClient.shutdown();
        }
        return checkUrl;
    }

    /**
     * 获取COS客户端实例
     *
     * @param storageConfig 存储配置对象
     * @return COS客户端实例
     */
    private static COSClient getCOSClient(StorageConfig storageConfig) {
        String secretId = storageConfig.getTencentSecretId();
        String secretKey = storageConfig.getTencentSecretKey();
        COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
        Region region = new Region(storageConfig.getTencentRegion());
        ClientConfig clientConfig = new ClientConfig(region);
        clientConfig.setHttpProtocol(HttpProtocol.https);
        COSClient cosClient = new COSClient(cred, clientConfig);
        // 双重校验锁
        if (!cosClient.doesBucketExist(storageConfig.getTencentBucket())) {
            synchronized (FileServerUtil.class) {
                // 不存在则创建桶
                if (!cosClient.doesBucketExist(storageConfig.getTencentBucket())) {
                    CreateBucketRequest createBucketRequest = new CreateBucketRequest(storageConfig.getTencentBucket());
                    // 设置 bucket 的权限为 Private(私有读写)、其他可选有 PublicRead（公有读私有写）、PublicReadWrite（公有读写）
                    createBucketRequest.setCannedAcl(CannedAccessControlList.Private);
                    cosClient.createBucket(createBucketRequest);
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        // 当前线程暂停10s，等待bucket创建完成
                        log.warn("Interrupted!", e);
                        Thread.currentThread().interrupt();
                    } finally {
                        cosClient.shutdown();
                    }
                }
            }
        }
        return cosClient;
    }

    private static String checkUrl(String url, String filePath) {
        if (url.endsWith("/")) {
            return url + filePath;
        } else {
            return url + "/" + filePath;
        }
    }

}
